package com.bridgeintelligent.tag.webserver.security;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wayneleo.quickstart.ErrorDefinition;
import com.wayneleo.quickstart.QuickException;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.NoSuchElementException;

@Slf4j
public class JacksonHelper {

    private static ObjectMapper jackson;

    public static String toJson( Object bean ) {
        try {
            return getJackson().writeValueAsString( bean );
        }
        catch ( Exception e ) {
            throw QuickException.normal( new ErrorDefinition( 10106, "bean转json发生异常; BEAN --> {}" ) );
        }
    }

    public static <T> T toBean( String json, Class<T> type ) {
        try {
            return getJackson().readValue( json, type );
        }
        catch ( Exception e ) {
            throw QuickException.normal( new ErrorDefinition( 10105, "json转bean发生异常; JSON --> {}" ) );
        }
    }

    public static <T> T toBean( String json, JavaType type ) {
        try {
            return getJackson().readValue( json, type );
        }
        catch ( Exception e ) {
            throw QuickException.normal( new ErrorDefinition( 10105, "json转bean发生异常; JSON --> {}" ) );
        }
    }

    public static <T> T toBean( String json, TypeReference<T> type ) {
        try {
            return getJackson().readValue( json, type );
        }
        catch ( Exception e ) {
            throw QuickException.normal( new ErrorDefinition( 10105, "json转bean发生异常; JSON --> {}" ) );
        }
    }

    public static ObjectMapper getJackson() {
        if ( jackson == null ) {
            syncInitJackson();
        }
        return jackson;
    }

    private static synchronized void syncInitJackson() {
        if ( jackson != null ) {
            return;
        }
        Map<String, ObjectMapper> beanMapping = null;
        try {
            beanMapping = QuickBeanFactory.getBeans( ObjectMapper.class );
            jackson = beanMapping.entrySet().iterator().next().getValue();
        }
        catch ( NullPointerException npe ) {
            log.warn( "没有ApplicationContext，将使用默认Jackson配置\n" );
        }
        catch ( NoSuchElementException nsee ) {
            log.warn( "在ApplicationContext中没有找到ObjectMapper，将使用默认Jackson配置\n" );
        }
        if ( beanMapping == null || beanMapping.isEmpty() ) {
            jackson = new ObjectMapper();
            jackson.setSerializationInclusion( JsonInclude.Include.NON_NULL );
            jackson.disable( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES );
        }
    }

}
